package hr.sting.beans;

import hr.sting.droidorm.OrmException;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author mstipanov
 * @since 09.07.2010. 23:10:09
 */
public class PropertyInfo {
    private String name;
    private Field propertyField;
    private Method setterMethod;
    private Method getterMethod;
    private Class<?> propertyType;

    public PropertyInfo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setPropertyField(Field propertyField) {
        this.propertyField = propertyField;
    }

    public void setSetterMethod(Method setterMethod) {
        this.setterMethod = setterMethod;
    }

    public void setGetterMethod(Method getterMethod) {
        this.getterMethod = getterMethod;
    }

    public boolean isWrittable() {
        return null != setterMethod;
    }

    public Class<?> getPropertyType() {
        if (null != propertyType) {
            return propertyType;
        }

        propertyType = getterMethod.getReturnType();
        return propertyType;
    }

    public <T> void setValue(T t, Object value) throws InvocationTargetException, IllegalAccessException {
        setterMethod.invoke(t, value);
    }

    public <T> Object getValue(T t) {
        try {
            return getterMethod.invoke(t, null);
        } catch (Exception e) {
            throw new OrmException(e);
        }
    }

    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
        if (null != getterMethod) {
            T a = getterMethod.getAnnotation(annotationType);
            if (null != a) {
                return a;
            }
        }

        if (null != setterMethod) {
            T a = setterMethod.getAnnotation(annotationType);
            if (null != a) {
                return a;
            }
        }

        if (null != propertyField) {
            T a = propertyField.getAnnotation(annotationType);
            if (null != a) {
                return a;
            }
        }

        return null;
    }
}
